package logic

import (
	"context"
	"errors"
	"gozeroStandalone/define"
	"gozeroStandalone/internal/model"
	"gozeroStandalone/internal/svc"
	"gozeroStandalone/internal/tools"
	"gozeroStandalone/internal/types"
	"gozeroStandalone/utils"
	"time"

	"github.com/zeromicro/go-zero/core/logx"
)

/*
 +----------------------------------------------------------------------
 + Title        : AccountLogic
 + Author       : huwl
 + Version      : 1.0.0
 + Initial-Time : 2025-08-08
 + Last-time    : 这个文件最后修改的时间 + 修改人的名称
 + Desc         : 账户逻辑
 +----------------------------------------------------------------------
*/

type AccountLogic struct {
	BaseLogic
}

/**
 * 创建账户逻辑实例
 *
 * @param context.Context ctx ----------------------必传
 * @param *svc.ServiceContext svcCtx ---------------必传
 * @return *AccountLogic
 * @author huwl
 * @date 2025/10/31 12:54:03
 */
func NewAccountLogicInstance(ctx context.Context, svcCtx *svc.ServiceContext) *AccountLogic {
	return &AccountLogic{
		BaseLogic{
			Ctx:    ctx,
			SvcCtx: svcCtx,
			Logger: logx.WithContext(ctx),
		},
	}
}

/**
 * 新增
 *
 * @param types.AccountAddRequest params -------必传
 * @return error
 * @author huwl
 * @date 2025/10/31 12:54:03
 */
func (logic *AccountLogic) Add(params types.AccountAddRequest) error {
	if params.Username == "" {
		return errors.New("请输入用户名")
	}
	if !utils.CheckMobile(params.Mobile) {
		return errors.New("请输入正确格式的手机号")
	}
	if params.Title == "" {
		return errors.New("请输入职位")
	}
	if !utils.CheckEmail(params.Email) {
		return errors.New("请输入正确格式的邮箱")
	}

	// 验证用户名唯一性
	total, err := logic.SvcCtx.AccountModel.GetResultsByTotal(logic.Ctx, map[string]interface{}{
		"status <> (?)": -2,
		"username":      params.Username,
	})
	if err != nil {
		return err
	}
	if total > 0 {
		return errors.New("用户名重复,请重新输入")
	}

	// 验证手机号唯一性
	total, err = logic.SvcCtx.AccountModel.GetResultsByTotal(logic.Ctx, map[string]interface{}{
		"status <> (?)": -2,
		"mobile":        params.Mobile,
	})
	if err != nil {
		return err
	}
	if total > 0 {
		return errors.New("手机号重复,请重新输入")
	}

	bcryptPassword, _ := utils.Bcrypt("123456")
	// 操作数据库
	_, err = logic.SvcCtx.AccountModel.Insert(logic.Ctx, &model.MallAccount{
		Username:       params.Username,
		Name:           params.Name,
		Password:       bcryptPassword,
		Mobile:         params.Mobile,
		Title:          params.Title,
		Email:          params.Email,
		Avatar:         params.Avatar,
		IsCash:         uint8(params.IsCash),
		CreatePersonId: params.CreatePersonId,
		Note:           params.Note,
		Status:         1,
		CreateTime:     types.Now(),
	})
	if err != nil {
		return err
	}

	return nil
}

/**
 * 登录
 *
 * @param types.LoginAddRequest params ---------必传
 * @return map[string]interface{}, error
 * @author huwl
 * @date 2025/10/31 12:54:03
 */
func (logic *AccountLogic) Login(params types.AccountLoginRequest) (map[string]interface{}, error) {
	if params.Username == "" {
		return nil, errors.New("请输入用户名")
	}
	if params.Password == "" {
		return nil, errors.New("请输入密码")
	}

	//base64Captcha版
	b := tools.ValidateCaptcha(params.CaptchaId, params.Answer)
	if !b {
		return nil, errors.New("验证码错误")
	}

	// 获取账户信息
	account := model.MallAccount{}
	err := logic.SvcCtx.AccountModel.Row(logic.Ctx, &account, map[string]interface{}{
		"username": params.Username,
		"status":   1,
	})
	if err != nil {
		if err == model.ErrNotFound {
			return nil, errors.New("账户信息错误")
		}

		return nil, err
	}
	if !utils.CompareBcrypt(account.Password, params.Password) {
		return nil, errors.New("密码错误")
	}

	// 获取账户与角色的关联
	accountRoles := []*model.MallAccountRole{}
	err = logic.SvcCtx.AccountRoleModel.GetResultsByParams(logic.Ctx, &accountRoles, map[string]interface{}{
		"account_id": account.Id,
	}, 1, -1, "id DESC")
	if err != nil {
		return nil, err
	}

	// 组装角色Id
	roleIds := []int{}
	for _, accountRole := range accountRoles {
		roleIds = append(roleIds, int(accountRole.RoleId))
	}

	// 获取角色、权限
	roles := []*model.MallRole{}
	authes := []*model.MallAuth{}
	if len(roleIds) > 0 {
		err = logic.SvcCtx.RoleModel.GetResultsByParams(logic.Ctx, &roles, map[string]interface{}{
			"id IN (?)": roleIds,
		}, 1, -1, "id DESC")
		if err != nil {
			return nil, err
		}

		// 获取角色与权限关联
		roleAuthes := []*model.MallRoleAuth{}
		err = logic.SvcCtx.RoleAuthModel.GetResultsByParams(logic.Ctx, &roleAuthes, map[string]interface{}{
			"role_id IN (?)": roleIds,
		}, 1, -1, "id DESC")
		if err != nil {
			return nil, err
		}

		authIds := []int{}
		for _, roleAuth := range roleAuthes {
			authIds = append(authIds, int(roleAuth.AuthId))
		}

		if len(authIds) > 0 {
			err = logic.SvcCtx.AuthModel.GetResultsByParams(logic.Ctx, &authes, map[string]interface{}{
				"id IN (?)": authIds,
			}, 1, -1, "id DESC")
			if err != nil {
				return nil, err
			}
		}
	}

	// 生成token
	token, err := utils.GenerateToken(uint64(account.Id))
	if err != nil {
		return nil, err
	}

	return map[string]interface{}{
		"token":        token,
		"token_expire": time.Now().Add(time.Duration(define.TokenExpireTime)).Unix(),
		"account":      account,
		"roles":        roles,
		"authes":       authes,
	}, nil
}

/**
 * 账户详情
 *
 * @param uint16 accountId ---------------------非必传,账户Id
 * @return Json
 * @author huwl
 * @date 2025/10/31 12:54:03
 */
func (logic *AccountLogic) Detail(accountId uint16) (map[string]interface{}, error) {
	if accountId <= 0 {
		return nil, errors.New("账户Id错误")
	}

	// 获取账户
	account, err := logic.SvcCtx.AccountModel.FindOne(logic.Ctx, int64(accountId))
	if err != nil {
		return nil, err
	}

	// 获取账户与角色的关联
	accountRoles := []*model.MallAccountRole{}
	err = logic.SvcCtx.AccountRoleModel.GetResultsByParams(logic.Ctx, &accountRoles, map[string]interface{}{
		"account_id": account.Id,
	}, 1, -1, "id DESC")
	if err != nil {
		return nil, err
	}

	// 组装角色Id
	roleIds := []int{}
	for _, accountRole := range accountRoles {
		roleIds = append(roleIds, int(accountRole.RoleId))
	}

	// 获取角色、权限
	roles := []*model.MallRole{}
	authes := []*model.MallAuth{}
	if len(roleIds) > 0 {
		err = logic.SvcCtx.RoleModel.GetResultsByParams(logic.Ctx, &roles, map[string]interface{}{
			"id IN (?)": roleIds,
		}, 1, -1, "id DESC")
		if err != nil {
			return nil, err
		}

		// 获取角色与权限关联
		roleAuthes := []*model.MallRoleAuth{}
		err = logic.SvcCtx.RoleAuthModel.GetResultsByParams(logic.Ctx, &roleAuthes, map[string]interface{}{
			"role_id IN (?)": roleIds,
		}, 1, -1, "id DESC")
		if err != nil {
			return nil, err
		}

		authIds := []int{}
		for _, roleAuth := range roleAuthes {
			authIds = append(authIds, int(roleAuth.AuthId))
		}

		if len(authIds) > 0 {
			err = logic.SvcCtx.AuthModel.GetResultsByParams(logic.Ctx, &authes, map[string]interface{}{
				"id IN (?)": authIds,
			}, 1, -1, "id DESC")
			if err != nil {
				return nil, err
			}
		}
	}

	return map[string]interface{}{
		"account": account,
		"roles":   roles,
		"authes":  authes,
	}, nil
}
